package bdsimple.impl.mysql;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import bdsimple.abstractfactory.AbstractFactoryDAO;
import bdsimple.dao.base.CentroComercialDAO;
import bdsimple.dao.base.FabricaDAO;
import bdsimple.dao.base.NegocioDAO;
import bdsimple.dao.base.PropiedadDAO;
import bdsimple.dto.base.CentroComercialDTO;
import bdsimple.dto.base.FabricaDTO;
import bdsimple.dto.base.NegocioDTO;
import bdsimple.dto.base.PropiedadDTO;
import dao.base.api.IDTO;

public class PropiedadDAOImpl extends MySQLBaseDAO implements PropiedadDAO  {

	public PropiedadDAOImpl() {
		super(PropiedadDTO.class);	
	}

	@Override
	protected String createTableColumns() throws Exception {

		StringBuffer strbuf = new StringBuffer();

		strbuf.append(PropiedadDTOImpl.ID);
		strbuf.append(" INT PRIMARY KEY AUTO_INCREMENT, ");
		strbuf.append(PropiedadDTOImpl.NOMBRE);
		strbuf.append(" VARCHAR(50), ");
		strbuf.append(PropiedadDTOImpl.MINIMO_SIRVIENTES);
		strbuf.append(" INT, ");
		strbuf.append(PropiedadDTOImpl.SEGURIDAD_MINIMA);
		strbuf.append(" INT, ");
		strbuf.append(PropiedadDTOImpl.SEGURIDAD_MAXIMA);
		strbuf.append(" INT ");

		return strbuf.toString();

	}

	@Override
	protected String createInsertCollst(IDTO dto) throws Exception {

		StringBuffer strbuf = new StringBuffer();

		strbuf.append(PropiedadDTOImpl.NOMBRE);
		strbuf.append(", ");
		strbuf.append(PropiedadDTOImpl.MINIMO_SIRVIENTES);
		strbuf.append(", ");
		strbuf.append(PropiedadDTOImpl.SEGURIDAD_MINIMA);
		strbuf.append(", ");
		strbuf.append(PropiedadDTOImpl.SEGURIDAD_MAXIMA);

		return strbuf.toString();

	}

	@Override
	protected String createInsertValues(IDTO dto) throws Exception {

		PropiedadDTOImpl propiedadDTOImpl = (PropiedadDTOImpl) dto;

		StringBuffer strbuf = new StringBuffer();

		strbuf.append(singleQuotes(propiedadDTOImpl.getNombre()));
		strbuf.append(", ");
		strbuf.append(propiedadDTOImpl.getMinimoSirvientes());
		strbuf.append(", ");
		strbuf.append(propiedadDTOImpl.getSeguridadMinima());
		strbuf.append(", ");
		strbuf.append(propiedadDTOImpl.getSeguridadMaxima());

		return strbuf.toString();

	}

	@Override
	protected String createUpdateValues(IDTO dto) throws Exception {

		PropiedadDTOImpl propiedadDTOImpl = (PropiedadDTOImpl) dto;

		StringBuffer strbuf = new StringBuffer();

		strbuf.append(PropiedadDTOImpl.NOMBRE);
		strbuf.append(" = ");
		strbuf.append(singleQuotes(propiedadDTOImpl.getNombre()));

		strbuf.append(", ");

		strbuf.append(PropiedadDTOImpl.MINIMO_SIRVIENTES);
		strbuf.append(" = ");
		strbuf.append(propiedadDTOImpl.getMinimoSirvientes());

		strbuf.append(", ");

		strbuf.append(PropiedadDTOImpl.SEGURIDAD_MINIMA);
		strbuf.append(" = ");
		strbuf.append(propiedadDTOImpl.getSeguridadMinima());

		strbuf.append(", ");

		strbuf.append(PropiedadDTOImpl.SEGURIDAD_MAXIMA);
		strbuf.append(" = ");
		strbuf.append(propiedadDTOImpl.getSeguridadMaxima());

		return strbuf.toString();

	}


	public void update(IDTO dto) throws Exception {
		if (dto instanceof NegocioDAO) {
			NegocioDAO negocioDAO = (NegocioDAO) //
			AbstractFactoryDAO.getFactoryDAO().getDAO( //
					NegocioDAO.class, connectionBean);

			negocioDAO.update(dto);

			return;
		}

		if (dto instanceof CentroComercialDAO) {
			CentroComercialDAO centroComercialDAO = (CentroComercialDAO) //
			AbstractFactoryDAO.getFactoryDAO().getDAO( //
					CentroComercialDAO.class, connectionBean);

			centroComercialDAO.update(dto);

			return;
		}

		if (dto instanceof FabricaDTO) {
			FabricaDAO fabricaDAO = (FabricaDAO) //
			AbstractFactoryDAO.getFactoryDAO().getDAO( //
					FabricaDAO.class, connectionBean);

			fabricaDAO.update(dto);	    	

		}
	}
	public void delete(IDTO dto) throws Exception {
		if (dto instanceof NegocioDTO) {
			NegocioDAO negocioDAO = (NegocioDAO) //
			AbstractFactoryDAO.getFactoryDAO().getDAO( //
					NegocioDAO.class, connectionBean);

			negocioDAO.delete(dto);

			return;
		}

		if (dto instanceof CentroComercialDTO) {
			CentroComercialDAO centroComercialDAO = (CentroComercialDAO) //
			AbstractFactoryDAO.getFactoryDAO().getDAO( //
					CentroComercialDAO.class, connectionBean);

			centroComercialDAO.delete(dto);

			return;
		}

		if (dto instanceof FabricaDTO) {
			FabricaDAO fabricaDAO = (FabricaDAO) //
			AbstractFactoryDAO.getFactoryDAO().getDAO( //
					FabricaDAO.class, connectionBean);

			fabricaDAO.delete(dto);	    	

			return;
		}
	}

	public void insert(IDTO dto) throws Exception {
		if (dto instanceof NegocioDTO) {
			NegocioDAO negocioDAO = (NegocioDAO) //
			AbstractFactoryDAO.getFactoryDAO().getDAO( //
					NegocioDAO.class, connectionBean);

			negocioDAO.insert(dto);

			return;
		}

		if (dto instanceof CentroComercialDTO) {
			CentroComercialDAO centroComercialDAO = (CentroComercialDAO) //
			AbstractFactoryDAO.getFactoryDAO().getDAO( //
					CentroComercialDAO.class, connectionBean);

			centroComercialDAO.insert(dto);

			return;
		}

		if (dto instanceof FabricaDTO) {
			FabricaDAO fabricaDAO = (FabricaDAO) //
			AbstractFactoryDAO.getFactoryDAO().getDAO( //
					FabricaDAO.class, connectionBean);

			fabricaDAO.insert(dto);

			return;

		}
	}

	public List<IDTO> listAll(int lim, int off) throws Exception {

		FabricaDAO fabricaDAO = (FabricaDAO) //
		AbstractFactoryDAO.getFactoryDAO().getDAO( //
				FabricaDAO.class, connectionBean);

		CentroComercialDAO centroComercialDAO = (CentroComercialDAO) //
		AbstractFactoryDAO.getFactoryDAO().getDAO( //
				CentroComercialDAO.class, connectionBean);

		NegocioDAO negocioDAO = (NegocioDAO) //
		AbstractFactoryDAO.getFactoryDAO().getDAO( // 
				NegocioDAO.class, connectionBean);

		StringBuffer strbuf = new StringBuffer();

		// SELECT publication.*, 'dao.example.base.BookDTO' AS dtoClass FROM
		//   publication, book
		//   WHERE
		//     book.id == publication.id
		strbuf.append("SELECT " + getTableName() + ".*, '" + //
				FabricaDTO.class.getSimpleName() + "' AS dtoClass FROM ");

		strbuf.append(this.getTableName() + ", " + fabricaDAO.getTableName());
		strbuf.append(" WHERE  " + //
				fabricaDAO.getTableName() + "." + FabricaDTO.ID + //
				" = " + //
				this.getTableName() + "." + PropiedadDTO.ID);

		strbuf.append(" UNION ");

		// SELECT publication.*, 'dao.example.base.NewsDTO' AS dtoClass FROM
		//   publication, news
		//   WHERE
		//     news.id == publication.id
		strbuf.append("SELECT " + getTableName() + ".*, '" + //
				CentroComercialDTO.class.getSimpleName() + "' AS dtoClass FROM ");

		strbuf.append(this.getTableName() + ", " + centroComercialDAO.getTableName());
		strbuf.append(" WHERE  " + //
				centroComercialDAO.getTableName() + "." + CentroComercialDTO.ID + //
				" = " + //
				this.getTableName() + "." + PropiedadDTO.ID);

		strbuf.append(" UNION ");

		strbuf.append("SELECT " + getTableName() + ".*, '" + //
				NegocioDTO.class.getSimpleName() + "' AS dtoClass FROM ");

		strbuf.append(this.getTableName() + ", " + negocioDAO.getTableName());
		strbuf.append(" WHERE  " + //
				negocioDAO.getTableName() + "." + NegocioDTO.ID + //
				" = " + //
				this.getTableName() + "." + PropiedadDTO.ID);

		if (lim >= 0 && off >= 0) {
			strbuf.append(" LIMIT  ");
			strbuf.append(lim);
			strbuf.append(" OFFSET ");
			strbuf.append(off);
		}

		System.err.println(strbuf.toString());

		ResultSet rs = //
			connection.createStatement().executeQuery(strbuf.toString());

		List<IDTO> ret = new ArrayList<IDTO>();

		while (rs.next()) {
			ret.add(resultSetToDTO(rs));
		}

		return ret;
	}

	public List<IDTO> listBy(String key, Object val) throws Exception {

		FabricaDAO fabricaDAO = (FabricaDAO) //
		AbstractFactoryDAO.getFactoryDAO().getDAO( //
				FabricaDAO.class, connectionBean);

		CentroComercialDAO centroComercialDAO = (CentroComercialDAO) //
		AbstractFactoryDAO.getFactoryDAO().getDAO( //
				CentroComercialDAO.class, connectionBean);

		NegocioDAO negocioDAO = (NegocioDAO) //
		AbstractFactoryDAO.getFactoryDAO().getDAO( // 
				NegocioDAO.class, connectionBean);	

		StringBuffer strbuf = new StringBuffer();

		// SELECT publication.*, 'dao.example.base.BookDTO' AS dtoClass FROM
		//   publication, book
		//   WHERE
		//     book.id == publication.id
		strbuf.append("SELECT " + getTableName() + ".*, '" + //
				FabricaDTO.class.getSimpleName() + "' AS dtoClass FROM ");

		strbuf.append(this.getTableName() + ", " + fabricaDAO.getTableName());
		strbuf.append(" WHERE  " + //
				fabricaDAO.getTableName() + "." + FabricaDTO.ID + //
				" = " + //
				this.getTableName() + "." + PropiedadDTO.ID);
		strbuf.append(" AND ");
		strbuf.append(key);
		strbuf.append(" = ");
		strbuf.append(val);

		strbuf.append(" UNION ");

		// SELECT publication.*, 'dao.example.base.NewsDTO' AS dtoClass FROM
		//   publication, news
		//   WHERE
		//     news.id == publication.id
		strbuf.append("SELECT " + getTableName() + ".*, '" + //
				CentroComercialDTO.class.getSimpleName() + "' AS dtoClass FROM ");

		strbuf.append(this.getTableName() + ", " + centroComercialDAO.getTableName());
		strbuf.append(" WHERE  " + //
				centroComercialDAO.getTableName() + "." + CentroComercialDTO.ID + //
				" = " + //
				this.getTableName() + "." + PropiedadDTO.ID);
		strbuf.append(" AND ");
		strbuf.append(key);
		strbuf.append(" = ");
		strbuf.append(val);

		strbuf.append(" UNION ");

		strbuf.append("SELECT " + getTableName() + ".*, '" + //
				NegocioDTO.class.getSimpleName() + "' AS dtoClass FROM ");

		strbuf.append(this.getTableName() + ", " + negocioDAO.getTableName());
		strbuf.append(" WHERE  " + //
				negocioDAO.getTableName() + "." + NegocioDTO.ID + //
				" = " + //
				this.getTableName() + "." + PropiedadDTO.ID);
		strbuf.append(" AND ");
		strbuf.append(key);
		strbuf.append(" = ");
		strbuf.append(val);


		System.err.println(strbuf.toString());

		ResultSet rs = //
			connection.createStatement().executeQuery(strbuf.toString());

		List<IDTO> ret = new ArrayList<IDTO>();

		while (rs.next()) {
			ret.add(resultSetToDTO(rs));
		}

		return ret;
	}


	protected PropiedadDTOImpl resultSetToDTO(ResultSet rs) throws Exception {
		
		PropiedadDTOImpl ret = (PropiedadDTOImpl) dtaSession.getDtaByKey( //
				PropiedadDTOImpl.class, rs.getInt(PropiedadDTOImpl.ID));

		if (ret != null) {
			return ret;
		}
		
		//---------------------------------------------------------------------------------
		if (rs.getString("dtoClass").equals(FabricaDTO.class.getSimpleName())) {			
			FabricaDAO fabricaDAO = (FabricaDAO) //
			AbstractFactoryDAO.getFactoryDAO().getDAO( //
					FabricaDAO.class, connectionBean);

			ret = (FabricaDTOImpl) fabricaDAO.loadById( //
					rs.getInt(FabricaDTOImpl.ID));

			return (FabricaDTOImpl) dtaSession.add(ret);
		}
		//---------------------------------------------------------------------------------
		if (rs.getString("dtoClass").equals(CentroComercialDTO.class.getSimpleName())) {
			CentroComercialDAO centroComercialDAO = (CentroComercialDAO) //
			AbstractFactoryDAO.getFactoryDAO().getDAO( //
					CentroComercialDAO.class, connectionBean);

			ret = (CentroComercialDTOImpl) centroComercialDAO.loadById( //
					rs.getInt(CentroComercialDTOImpl.ID));

			return (CentroComercialDTOImpl) dtaSession.add(ret);
		}
		//---------------------------------------------------------------------------------
		if (rs.getString("dtoClass").equals(NegocioDTO.class.getSimpleName())) {
			NegocioDAO negocioDAO = (NegocioDAO) //
			AbstractFactoryDAO.getFactoryDAO().getDAO( //
					NegocioDAO.class, connectionBean);

			ret = (NegocioDTOImpl) negocioDAO.loadById( //
					rs.getInt(NegocioDTOImpl.ID));

			return (NegocioDTOImpl) dtaSession.add(ret);
		}
		//---------------------------------------------------------------------------------
		
		throw new IllegalArgumentException(rs.getString("dtoClass"));

	}

	@Override
	protected IDTO internalResultSetToDTO(ResultSet rs, IDTO dto)
	throws Exception {

		PropiedadDTOImpl ret = (PropiedadDTOImpl) dto;

		ret.setId(rs.getInt(ProductoDTOImpl.ID));
		ret.setNombre(rs.getString(PropiedadDTOImpl.NOMBRE));
		ret.setMinimoSirvientes(rs.getInt(PropiedadDTOImpl.MINIMO_SIRVIENTES));
		ret.setSeguridadMinima(rs.getInt(PropiedadDTOImpl.SEGURIDAD_MINIMA));
		ret.setSeguridadMaxima(rs.getInt(PropiedadDTOImpl.SEGURIDAD_MAXIMA));

		return ret;

	}
	
	public byte[] loadImageByPropiedadId(int propiedadId) throws SQLException, Exception {
        StringBuffer strbuf = new StringBuffer();

        strbuf.append("SELECT ");
        strbuf.append(PropiedadDTO.IMAGEN);
        strbuf.append(" FROM ");
        strbuf.append(getTableName());
        strbuf.append(" WHERE ");
        strbuf.append(PropiedadDTO.ID);
        strbuf.append(" = ");
        strbuf.append(propiedadId);

        System.err.println(strbuf.toString());

        ResultSet rs = //
            connection.createStatement().executeQuery(strbuf.toString());
        
        if(rs.next()) {
            return rs.getBytes(PropiedadDTO.IMAGEN);
        }
        
        return null;
    }

}

